package com.situ.skymallproductcategoryapi.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.situ.model.ProductCategory;
import com.situ.service.ProductCategoryService;
import com.situ.skymallproductcategoryapi.mapper.ProductCategoryMapper;
import jdk.jfr.Category;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@CacheConfig(cacheNames = "skymall-productCategory")
@Service
public class ProductCategoryServiceImpl implements ProductCategoryService {
    private ProductCategoryMapper productCategoryMapper;
    //private RedisTemplate<String, Object> redisTemplate;

//    @Autowired
//    public void setRedisTemplate (RedisTemplate<String, Object> redisTemplate) {
//        this.redisTemplate = redisTemplate;
//    }

    @Autowired
    public ProductCategoryServiceImpl(ProductCategoryMapper productCategoryMapper) {
        this.productCategoryMapper = productCategoryMapper;
    }

    /*
      后台查询商品类别
      @param page 分页参数
      @param search 查询条件
      @return 商品类别列表
     */
    @Override
    public Page<ProductCategory> getList(Page<ProductCategory> page, ProductCategory search) {
        return productCategoryMapper.getList(page, search);
    }

    /*
      前台查询所有商品类别
      @return 商品类别列表
    */
    @Cacheable(key = "'list'")
    @Override
    public List<ProductCategory> getList() {
        return productCategoryMapper.selectList(null);
    }

    /*
      获取商品类别树形列表
      @return 商品类别树形列表
     */
    @Cacheable(key = "'tree'")
    @Override
    public List<ProductCategory> getTreeList() {
        //使用代理调用，可以触发aop
        List<ProductCategory> list = getProxy().getList();
        return makeTreeList(list);
    }

    /*
      获取商品类别详情
      @param id 商品类别ID
      @return 商品类别详情
     */
    @Cacheable(key = "'id:' + #id")
    @Override
    public ProductCategory getById(Integer id) {
        //使用代理调用，可以触发aop
        List<ProductCategory> list = getProxy().getTreeList();
        return getById(list, id);
    }

    /*
      保存商品类别
      @param productCategory 商品类别
      @return 是否保存成功
     */
    @CacheEvict(allEntries = true)
    @Override
    public boolean save(ProductCategory productCategory) {
        return productCategoryMapper.insert(productCategory) == 1;
    }

    /*
      更新商品类别
      @param productCategory 待更新的商品类别
      @return 是否更新成功
     */
    @CacheEvict(allEntries = true)
    @Override
    public boolean updateById(ProductCategory productCategory) {
        return productCategoryMapper.updateById(productCategory) == 1;
    }

    /*
      删除商品类别
      @param id 待删除的商品类别ID
      @return 是否删除成功
     */
    @CacheEvict(allEntries = true)
    @Override
    public boolean deleteById(Integer id) {
        //使用代理调用，可以触发aop
        ProductCategory productCategory = getProxy().getById(id);
        if (productCategory.getChildren() != null) {
            throw new UnsupportedOperationException("该分类下有子分类，无法删除");
        }
        return productCategoryMapper.deleteById(id) == 1;
    }

    /*
      切换展示商品类别（开启/关闭）
      @param id 待改变状态的商品类别ID
      @return 是否切换成功
     */
    @CacheEvict(allEntries = true)
    @Override
    public boolean toggleShow(Integer id) {
        ProductCategory productCategory = productCategoryMapper.selectById(id);
        int isShow = productCategory.getIsShow();
        if (isShow == 1) {
            return productCategoryMapper.updateShow(id, 0) == 1;
        } else {
            return productCategoryMapper.updateShow(id, 1) == 1;
        }
    }

    /*
      生成树形列表
      @param list 待处理的列表
      @return 处理后的树形列表
     */
    private List<ProductCategory> makeTreeList(List<ProductCategory> list) {
        List<ProductCategory> roots = new ArrayList<>();

        //缓存id 方便查找
        Map<Integer, ProductCategory> cache = new HashMap<>();
        for (ProductCategory productCategory : list) {
            cache.put(productCategory.getId(), productCategory);
        }
        //遍历
        for (ProductCategory productCategory : cache.values()) {
            if (productCategory.getParentId() == 0) { //判断是否是根节点
                //添加到根节点列表中
                roots.add(productCategory);
            } else {
                ProductCategory parent = cache.get(productCategory.getParentId());
                if (parent == null) {
                    throw new RuntimeException("父节点不存在");
                } else {
                    productCategory.setParent(parent);
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(productCategory);
                }
            }
        }
        return roots;
    }

    /*
      在分类集合中找到指定编号的分类
      @param list 分类集合
      @param id 分类编号
      @return 分类
     */
    private ProductCategory getById(List<ProductCategory> list, Integer id) {
        for (ProductCategory productCategory : list) {
            if (productCategory.getId().equals(id)) {
                return productCategory;
            }
            if (productCategory.getChildren() != null) {
                ProductCategory productCategory1 = getById(productCategory.getChildren(), id);
                if (productCategory1 != null) {
                    return productCategory1;
                }
            }
        }
        return null;
    }

    /*
      获取当前类的代理实现
      @return 当前类的代理实现
     */
    private ProductCategoryService getProxy() {
        return (ProductCategoryService) AopContext.currentProxy();
    }
}
